import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

# 参数设置
U = 1.0       # 来流速度
a = 1.0       # 圆柱半径
Gamma_min = -4 * np.pi * U * a  # Γ最小值
Gamma_max = 4 * np.pi * U * a   # Γ最大值

# 创建网格
x = np.linspace(-3*a, 3*a, 100)
y = np.linspace(-3*a, 3*a, 100)
X, Y = np.meshgrid(x, y)
R = np.sqrt(X**2 + Y**2)
Theta = np.arctan2(Y, X)

# 创建图形和轴
fig, ax = plt.subplots(figsize=(8, 8))
ax.set_xlim(-3*a, 3*a)
ax.set_ylim(-3*a, 3*a)
ax.set_aspect('equal')
ax.set_xlabel('x')
ax.set_ylabel('y')

# 绘制圆柱
cylinder = plt.Circle((0, 0), a, color='white', zorder=10)
ax.add_patch(cylinder)

# 初始Γ值
Gamma = 0.0

# 计算初始流函数ψ
psi = U * Y * (1 - (a**2)/(X**2 + Y**2)) + (Gamma/(4*np.pi)) * np.log(X**2 + Y**2)

# 绘制初始流线
contour = ax.contour(X, Y, psi, levels=30, colors='blue')

# 设置标题
ax.set_title(f'Flow around a cylinder with Γ = {Gamma:.2f}')

# 创建滑条轴
slider_ax = plt.axes([0.2, 0.05, 0.6, 0.03])
gamma_slider = Slider(slider_ax, 'Γ', Gamma_min, Gamma_max, valinit=Gamma)

# 更新函数
def update(val):
    global contour
    Gamma = gamma_slider.val
    
    # 清除之前的流线
    ax.clear()
    
    # 绘制圆柱
    ax.add_patch(plt.Circle((0, 0), a, color='white', zorder=10))
    
    # 设置坐标轴范围和标题
    ax.set_xlim(-3*a, 3*a)
    ax.set_ylim(-3*a, 3*a)
    ax.set_aspect('equal')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    
    # 计算新的流函数ψ
    psi = U * Y * (1 - (a**2)/(X**2 + Y**2)) + (Gamma/(4*np.pi)) * np.log(X**2 + Y**2)
    
    # 绘制新的流线
    contour = ax.contour(X, Y, psi, levels=30, colors='blue')
    
    # 更新标题
    ax.set_title(f'Flow around a cylinder with Γ = {Gamma:.2f}')
    
    # 重新绘制图形
    fig.canvas.draw_idle()

# 绑定滑条事件
gamma_slider.on_changed(update)

# 显示图形
plt.show()